package org.estela.util;

/**
 * MinMax from Cormen... (CLRS)
 *
 * @version $Revision: 1.3 $
 * @author <a href="mailto:akantek@nyse.com">Antonio Kantek</a>
 */

public class MinMax {
	
	/**
	 * Returns the index of the maximum element in the array passed as argument.
	 * 
	 * @param values -
	 *            values to be tested
	 * @return the index of the max value
	 */
	public static int maxIndex(double[] values) {
		double maximum = 0;
		int maxIndex = 0;
		for (int i = 0; i < values.length; i++) {
			if ((i == 0) || (values[i] > maximum)) {
				maxIndex = i;
				maximum = values[i];
			}
		}
		return maxIndex;
	}	
    
    public static int[] getMinMax(final int[] numbers) {
        int[] minMax = new int[2];
        int j;      
        if (numbers.length % 2 == 0) { //numero par
            if (numbers[0] < numbers[1]) {
                minMax[0] = numbers[0];
                minMax[1] = numbers[1];             
            } else {
                minMax[0] = numbers[1];
                minMax[1] = numbers[0];             
            }

            for (int i = 0; i < numbers.length; i+=2) {
                j = i + 1;
                if (numbers[i] < numbers[j]) {
                    if (numbers[i] < minMax[0]) {
                        minMax[0] = numbers[i];
                    }
                    if (numbers[j] > minMax[1] ) {
                        minMax[1] = numbers[j];
                    }
                } else {
                    if (numbers[j] < minMax[0]) {
                        minMax[0] = numbers[j];
                    }
                    if (numbers[i] > minMax[1] ) {
                        minMax[1] = numbers[i];
                    }
                }
            }
            
        } else { //numero impar 
            minMax[0] = minMax[1] = numbers[0];
            for (int i = 1; i < numbers.length; i+=2) {
                j = i + 1;
                if (numbers[i] < numbers[j]) {
                    if (numbers[i] < minMax[0]) {
                        minMax[0] = numbers[i];
                    }
                    if (numbers[j] > minMax[1] ) {
                        minMax[1] = numbers[j];
                    }
                } else {
                    if (numbers[j] < minMax[0]) {
                        minMax[0] = numbers[j];
                    }
                    if (numbers[i] > minMax[1] ) {
                        minMax[1] = numbers[i];
                    }
                }
            }           
        } 
        return minMax;
    }

    public static long[] getMinMax(long[] numbers) {
        long[] minMax = new long[2];
        int j;      
        if (numbers.length % 2 == 0) { //pair number
            if (numbers[0] < numbers[1]) {
                minMax[0] = numbers[0];
                minMax[1] = numbers[1];             
            } else {
                minMax[0] = numbers[1];
                minMax[1] = numbers[0];             
            }

            for (int i = 0; i < numbers.length; i+=2) {
                j = i + 1;
                if (numbers[i] < numbers[j]) {
                    if (numbers[i] < minMax[0]) {
                        minMax[0] = numbers[i];
                    }
                    if (numbers[j] > minMax[1] ) {
                        minMax[1] = numbers[j];
                    }
                } else {
                    if (numbers[j] < minMax[0]) {
                        minMax[0] = numbers[j];
                    }
                    if (numbers[i] > minMax[1] ) {
                        minMax[1] = numbers[i];
                    }
                }
            }
            
        } else { //numero impar 
            minMax[0] = minMax[1] = numbers[0];
            for (int i = 1; i < numbers.length; i+=2) {
                j = i + 1;
                if (numbers[i] < numbers[j]) {
                    if (numbers[i] < minMax[0]) {
                        minMax[0] = numbers[i];
                    }
                    if (numbers[j] > minMax[1] ) {
                        minMax[1] = numbers[j];
                    }
                } else {
                    if (numbers[j] < minMax[0]) {
                        minMax[0] = numbers[j];
                    }
                    if (numbers[i] > minMax[1] ) {
                        minMax[1] = numbers[i];
                    }
                }
            }           
        } 
        return minMax;

    }   

    public static float[] getMinMax(float[] numbers) {
        float[] minMax = new float[2];
        int j;      
        if (numbers.length % 2 == 0) { //numero par
            if (numbers[0] < numbers[1]) {
                minMax[0] = numbers[0];
                minMax[1] = numbers[1];             
            } else {
                minMax[0] = numbers[1];
                minMax[1] = numbers[0];             
            }

            for (int i = 0; i < numbers.length; i+=2) {
                j = i + 1;
                if (numbers[i] < numbers[j]) {
                    if (numbers[i] < minMax[0]) {
                        minMax[0] = numbers[i];
                    }
                    if (numbers[j] > minMax[1] ) {
                        minMax[1] = numbers[j];
                    }
                } else {
                    if (numbers[j] < minMax[0]) {
                        minMax[0] = numbers[j];
                    }
                    if (numbers[i] > minMax[1] ) {
                        minMax[1] = numbers[i];
                    }
                }
            }
            
        } else { //numero impar 
            minMax[0] = minMax[1] = numbers[0];
            for (int i = 1; i < numbers.length; i+=2) {
                j = i + 1;
                if (numbers[i] < numbers[j]) {
                    if (numbers[i] < minMax[0]) {
                        minMax[0] = numbers[i];
                    }
                    if (numbers[j] > minMax[1] ) {
                        minMax[1] = numbers[j];
                    }
                } else {
                    if (numbers[j] < minMax[0]) {
                        minMax[0] = numbers[j];
                    }
                    if (numbers[i] > minMax[1] ) {
                        minMax[1] = numbers[i];
                    }
                }
            }           
        } 
        return minMax;
    }

    public static double[] getMinMax(double[] numbers) {
        double[] minMax = new double[2];
        int j;      
        if (numbers.length % 2 == 0) { //numero par
            if (numbers[0] < numbers[1]) {
                minMax[0] = numbers[0];
                minMax[1] = numbers[1];             
            } else {
                minMax[0] = numbers[1];
                minMax[1] = numbers[0];             
            }

            for (int i = 0; i < numbers.length; i+=2) {
                j = i + 1;
                if (numbers[i] < numbers[j]) {
                    if (numbers[i] < minMax[0]) {
                        minMax[0] = numbers[i];
                    }
                    if (numbers[j] > minMax[1] ) {
                        minMax[1] = numbers[j];
                    }
                } else {
                    if (numbers[j] < minMax[0]) {
                        minMax[0] = numbers[j];
                    }
                    if (numbers[i] > minMax[1] ) {
                        minMax[1] = numbers[i];
                    }
                }
            }
            
        } else { //numero impar 
            minMax[0] = minMax[1] = numbers[0];
            for (int i = 1; i < numbers.length; i+=2) {
                j = i + 1;
                if (numbers[i] < numbers[j]) {
                    if (numbers[i] < minMax[0]) {
                        minMax[0] = numbers[i];
                    }
                    if (numbers[j] > minMax[1] ) {
                        minMax[1] = numbers[j];
                    }
                } else {
                    if (numbers[j] < minMax[0]) {
                        minMax[0] = numbers[j];
                    }
                    if (numbers[i] > minMax[1] ) {
                        minMax[1] = numbers[i];
                    }
                }
            }           
        } 
        return minMax;
    }

	public static double max(double[] distributions) {
		double max = distributions[0];
		for(int i=1;i<distributions.length;i++) {
			if (distributions[i] > max) {
				max = distributions[i];
			}
		}
		return max;
	}

    /*
    public static void getMinMax(Object[] objects, Comparator c, Object[] minMax) {
        int j;      
        if (objects.length % 2 == 0) { //numero par
            if (c.compare(objects[0],objects[1]) < 0) {
                minMax[0] = objects[0];
                minMax[1] = objects[1];             
            } else {
                minMax[0] = objects[1];
                minMax[1] = objects[0];             
            }

            for (int i = 0; i < objects.length; i+=2) {
                j = i + 1;
                if (c.compare(objects[i],objects[j]) < 0) {
                    if (c.compare(objects[i],minMax[0]) < 0) {
                        minMax[0] = objects[i];
                    }
                    if (c.compare(objects[j],minMax[1]) > 0) {
                        minMax[1] = objects[j];
                    }
                } else {
                    if (c.compare(objects[j],minMax[0]) < 0) {
                        minMax[0] = objects[j];
                    }
                    if (c.compare(objects[i],minMax[1]) > 0) {
                        minMax[1] = objects[i];
                    }
                }
            }
            
        } else { //numero impar 
            minMax[0] = minMax[1] = objects[0];
            for (int i = 1; i < objects.length; i+=2) {
                j = i + 1;
                if (c.compare(objects[i],objects[j]) < 0) {
                    if (c.compare(objects[i],minMax[0]) <0) {
                        minMax[0] = objects[i];
                    }
                    if (c.compare(objects[j], minMax[1]) > 0) {
                        minMax[1] = objects[j];
                    }
                } else {
                    if (c.compare(objects[j],minMax[0]) < 0) {
                        minMax[0] = objects[j];
                    }
                    if (c.compare(objects[i],minMax[1]) > 0) {
                        minMax[1] = objects[i];
                    }
                }
            }           
        }
    }

    public static void getMinMax(Comparable[] objects, Object[] minMax) {
        int j;      
        if (objects.length % 2 == 0) { //numero par
            if (objects[0].compareTo(objects[1]) < 0) {
                minMax[0] = objects[0];
                minMax[1] = objects[1];             
            } else {
                minMax[0] = objects[1];
                minMax[1] = objects[0];             
            }

            for (int i = 0; i < objects.length; i+=2) {
                j = i + 1;
                if (objects[i].compareTo(objects[j]) < 0) {
                    if (objects[i].compareTo(minMax[0]) < 0) {
                        minMax[0] = objects[i];
                    }
                    if (objects[j].compareTo(minMax[1]) > 0) {
                        minMax[1] = objects[j];
                    }
                } else {
                    if (objects[j].compareTo(minMax[0]) < 0) {
                        minMax[0] = objects[j];
                    }
                    if (objects[i].compareTo(minMax[1]) > 0) {
                        minMax[1] = objects[i];
                    }
                }
            }
            
        } else { //numero impar 
            minMax[0] = minMax[1] = objects[0];
            for (int i = 1; i < objects.length; i+=2) {
                j = i + 1;
                if (objects[i].compareTo(objects[j]) < 0) {
                    if (objects[i].compareTo(minMax[0]) <0) {
                        minMax[0] = objects[i];
                    }
                    if (objects[j].compareTo(minMax[1]) > 0) {
                        minMax[1] = objects[j];
                    }
                } else {
                    if (objects[j].compareTo(minMax[0]) < 0) {
                        minMax[0] = objects[j];
                    }
                    if (objects[i].compareTo(minMax[1]) > 0) {
                        minMax[1] = objects[i];
                    }
                }
            }           
        }
    }*/

}

